using System;
using System.Threading;
using FXEtherCATSDKWrapper;

/**
 * 位操作滤波器示例
 * 
 * 演示如何使用位操作功能监控uint8类型PDO中的特定位
 * 适用于多IO模块、IO扩展板等场景
 * 
 * 示例场景：
 * 0x6000:1 = UINT8，包含8个IO：
 * Bit 7-4: 4个光电传感器
 * Bit 3-0: 4个按钮
 */
class BitOperationExample
{
    private static FXEtherCATSDK? _sdk;
    private static bool _running = true;

    // 配置常量
    private const ushort SLAVE_NUMBER = 0;
    private const ushort IO_MODULE_INDEX = 0x6000;
    private const byte IO_MODULE_SUBINDEX = 1;

    static void Main(string[] args)
    {
        Console.WriteLine("=== 位操作滤波器示例 ===");
        Console.WriteLine("演示如何监控uint8类型PDO中的特定位");
        Console.WriteLine();

        try
        {
            // 1. 初始化SDK
            _sdk = new FXEtherCATSDK();
            if (!_sdk.Connect())
            {
                Console.WriteLine("❌ SDK连接失败");
                return;
            }
            Console.WriteLine("✓ SDK连接成功");

            // 2. 配置实时监控线程
            _sdk.ConfigureMonitorThread(2, 85);
            Console.WriteLine("✓ 实时监控线程已配置");

            // 3. 配置多个位操作滤波器
            ConfigureBitFilters();

            // 4. 注册回调事件
            RegisterCallbacks();

            // 5. 启动监控
            if (!_sdk.StartReadDataMonitoring())
            {
                Console.WriteLine("❌ 启动数据监控失败");
                return;
            }
            Console.WriteLine("✓ 数据监控已启动");

            // 6. 显示滤波器状态
            DisplayFilterStatus();

            // 7. 等待用户输入
            Console.WriteLine("\n按任意键退出...");
            Console.ReadKey();
            _running = false;

            // 8. 清理资源
            _sdk.StopReadDataMonitoring();
            _sdk.Dispose();
            Console.WriteLine("✓ 资源已清理");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"❌ 程序异常: {ex.Message}");
        }
    }

    /// <summary>
    /// 配置各种位操作滤波器
    /// </summary>
    private static void ConfigureBitFilters()
    {
        Console.WriteLine("\n=== 配置位操作滤波器 ===");

        // 滤波器1：只监控光电传感器1（第7位）
        var photoelectric1Filter = new ReadDataFilter
        {
            Type = FilterType.SlidingWindow,
            WindowSizeMs = 50,
            RisingThreshold = 40,
            FallingThreshold = 30,
            MonitoredBits = { 7 },          // 只监控Bit 7
            Logic = BitLogic.Any,
            EdgeType = EdgeType.Both
        };
        _sdk!.ConfigureReadDataFilter(SLAVE_NUMBER, IO_MODULE_INDEX, IO_MODULE_SUBINDEX, photoelectric1Filter);
        Console.WriteLine("✓ 光电传感器1滤波器已配置 (Bit 7)");

        // 滤波器2：监控任意光电传感器（第7-4位）
        var anyPhotoelectricFilter = new ReadDataFilter
        {
            Type = FilterType.SlidingWindow,
            WindowSizeMs = 30,
            RisingThreshold = 25,
            FallingThreshold = 15,
            MonitoredBits = { 7, 6, 5, 4 }, // 监控4个光电传感器
            Logic = BitLogic.Any,           // 任意一个触发就算
            EdgeType = EdgeType.Both
        };
        // 注意：这里使用不同的subindex来区分不同的滤波器
        _sdk!.ConfigureReadDataFilter(SLAVE_NUMBER, IO_MODULE_INDEX, 2, anyPhotoelectricFilter);
        Console.WriteLine("✓ 任意光电传感器滤波器已配置 (Bit 7-4, Any)");

        // 滤波器3：双光电防重复计数（第7位和第6位都触发才算）
        var dualPhotoelectricFilter = new ReadDataFilter
        {
            Type = FilterType.SlidingWindow,
            WindowSizeMs = 50,
            RisingThreshold = 40,
            FallingThreshold = 30,
            MonitoredBits = { 7, 6 },       // 监控Bit 7和Bit 6
            Logic = BitLogic.All,           // 两个都为1才触发
            EdgeType = EdgeType.Both
        };
        _sdk!.ConfigureReadDataFilter(SLAVE_NUMBER, IO_MODULE_INDEX, 3, dualPhotoelectricFilter);
        Console.WriteLine("✓ 双光电防重复计数滤波器已配置 (Bit 7+6, All)");

        // 滤波器4：按钮组合（第3-0位，任意一个按下）
        var anyButtonFilter = new ReadDataFilter
        {
            Type = FilterType.SlidingWindow,
            WindowSizeMs = 20,              // 按钮响应更快
            RisingThreshold = 15,
            FallingThreshold = 10,
            MonitoredBits = { 3, 2, 1, 0 }, // 监控4个按钮
            Logic = BitLogic.Any,           // 任意一个按下就触发
            EdgeType = EdgeType.Rising      // 只检测按下，不检测释放
        };
        _sdk!.ConfigureReadDataFilter(SLAVE_NUMBER, IO_MODULE_INDEX, 4, anyButtonFilter);
        Console.WriteLine("✓ 任意按钮滤波器已配置 (Bit 3-0, Any, Rising)");

        // 滤波器5：紧急停止组合（第1位和第0位同时按下）
        var emergencyStopFilter = new ReadDataFilter
        {
            Type = FilterType.SlidingWindow,
            WindowSizeMs = 10,              // 紧急停止需要快速响应
            RisingThreshold = 8,
            FallingThreshold = 5,
            MonitoredBits = { 1, 0 },       // 监控两个紧急停止按钮
            Logic = BitLogic.All,           // 两个都按下才触发
            EdgeType = EdgeType.Rising      // 只检测按下
        };
        _sdk!.ConfigureReadDataFilter(SLAVE_NUMBER, IO_MODULE_INDEX, 5, emergencyStopFilter);
        Console.WriteLine("✓ 紧急停止滤波器已配置 (Bit 1+0, All, Rising)");
    }

    /// <summary>
    /// 注册回调事件
    /// </summary>
    private static void RegisterCallbacks()
    {
        _sdk!.SlaveReadDataChanged += (sender, e) =>
        {
            if (!_running) return;

            if (e.SlaveNumber == SLAVE_NUMBER && e.Index == IO_MODULE_INDEX)
            {
                string timestamp = DateTime.Now.ToString("HH:mm:ss.fff");
                
                switch (e.Subindex)
                {
                    case 1:
                        Console.WriteLine($"[{timestamp}] 📷 光电传感器1触发 (Bit 7) - 值: {e.NewValue}");
                        break;
                    case 2:
                        Console.WriteLine($"[{timestamp}] 📷 任意光电传感器触发 (Bit 7-4) - 值: {e.NewValue}");
                        break;
                    case 3:
                        Console.WriteLine($"[{timestamp}] 📷📷 双光电同时触发 (Bit 7+6) - 值: {e.NewValue}");
                        break;
                    case 4:
                        Console.WriteLine($"[{timestamp}] 🔘 按钮按下 (Bit 3-0) - 值: {e.NewValue}");
                        break;
                    case 5:
                        Console.WriteLine($"[{timestamp}] 🚨 紧急停止触发 (Bit 1+0) - 值: {e.NewValue}");
                        break;
                }
            }
        };
    }

    /// <summary>
    /// 显示滤波器状态
    /// </summary>
    private static void DisplayFilterStatus()
    {
        Console.WriteLine("\n=== 滤波器状态 ===");
        
        for (byte subindex = 1; subindex <= 5; subindex++)
        {
            var status = _sdk!.GetFilterStatus(SLAVE_NUMBER, IO_MODULE_INDEX, subindex);
            if (status != null)
            {
                string filterName = subindex switch
                {
                    1 => "光电传感器1",
                    2 => "任意光电传感器",
                    3 => "双光电防重复",
                    4 => "任意按钮",
                    5 => "紧急停止",
                    _ => $"滤波器{subindex}"
                };
                
                Console.WriteLine($"{filterName}: 活跃={status.IsActive}, 通过={status.PassedCount}, 过滤={status.FilteredCount}");
            }
        }
        
        Console.WriteLine("\n=== 监控中... ===");
        Console.WriteLine("模拟数据变化来测试滤波器:");
        Console.WriteLine("- Bit 7: 光电传感器1");
        Console.WriteLine("- Bit 6: 光电传感器2");
        Console.WriteLine("- Bit 5-4: 光电传感器3-4");
        Console.WriteLine("- Bit 3-2: 按钮1-2");
        Console.WriteLine("- Bit 1-0: 紧急停止按钮1-2");
    }
}
